package net.stuffrepos.bricknetcenter.gui.informations;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeModel;
import net.stuffrepos.bricknetcenter.database.schema.Information;
import net.stuffrepos.bricknetcenter.gui.Icons;
import net.stuffrepos.bricknetcenter.gui.MainFrame;
import net.stuffrepos.bricknetcenter.provider.HttpProviderManager;
import net.stuffrepos.bricknetcenter.util.gui.lazytree.LazyLoadingTreeController;
import net.stuffrepos.util.cache.CacheableValue;
import net.stuffrepos.util.listeners.Listener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 * @author Eduardo H. Bogoni <eduardobogoni@gmail.com>
 */
public class InformationsFrame extends javax.swing.JInternalFrame {

    private static final Log log = LogFactory.getLog(InformationsFrame.class);
    private Object selectedNode = null;
    private final AbstractAction startPauseAction;
    private final AbstractAction stopAction;
    private final CacheableValue<MainDetailPanel> mainDetailPanel = new CacheableValue<MainDetailPanel>() {

        @Override
        protected net.stuffrepos.bricknetcenter.gui.informations.MainDetailPanel calculate() {
            return new MainDetailPanel();
        }
    };
    private final CacheableValue<InformationDetail> informationDetailPanel = new CacheableValue<InformationDetail>() {

        @Override
        protected InformationDetail calculate() {
            return new InformationDetail(InformationsFrame.this);
        }
    };

    /** Creates new form ListInventoriesFrame */
    public InformationsFrame() {
        super("Informations", true, true, true, true);
        startPauseAction = new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    setControlsToHttpProviderActionBegin();
                    switch (HttpProviderManager.getInstance().getState()) {
                        case Running:
                            HttpProviderManager.getInstance().pause();
                            break;

                        case Paused:
                        case Stopped:
                            HttpProviderManager.getInstance().start();
                            break;

                    }


                } catch (Exception ex) {
                    log.warn("", ex);
                }
            }
        };

        stopAction = new AbstractAction(null, Icons.getIcon("stop.png")) {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    setControlsToHttpProviderActionBegin();
                    HttpProviderManager.getInstance().stop();
                } catch (Exception ex) {
                    log.warn("", ex);
                }
            }
        };

        stopAction.putValue(Action.SHORT_DESCRIPTION, "Stop seeker");

        initComponents();
        browser.addTreeSelectionListener(new TreeSelectionListener() {

            @Override
            public void valueChanged(TreeSelectionEvent e) {
                if (e == null || e.getNewLeadSelectionPath() == null || e.getNewLeadSelectionPath().getPathCount() == 0) {
                    setSelectedNode(null);
                } else if (e.getNewLeadSelectionPath().getPathCount() > 0) {
                    setSelectedNode(
                            e.getNewLeadSelectionPath().getPath()[e.getNewLeadSelectionPath().getPath().length - 1]);
                }
            }
        });
        browser.addTreeWillExpandListener(
                new LazyLoadingTreeController((DefaultTreeModel) browser.getModel()));
        startPauseAction.putValue(Action.SHORT_DESCRIPTION, "Start/resume seeker");
                                startPauseAction.putValue(Action.LARGE_ICON_KEY, Icons.getIcon("play.png"));
        setControlsToHttpProviderActionBegin();
        showMainDetail();
        
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                HttpProviderManager.getInstance().addStateChangeListener(new Listener<HttpProviderManager>() {

                    @Override
                    public void onChange(HttpProviderManager source) {
                        httpProviderManagerState.setText(source.getState().name());
                        startPauseAction.setEnabled(true);

                        switch (source.getState()) {
                            case Running:
                                startPauseAction.putValue(Action.SHORT_DESCRIPTION, "Pause seeker");
                                startPauseAction.putValue(Action.LARGE_ICON_KEY, Icons.getIcon("pause.png"));
                                stopAction.setEnabled(true);
                                httpProviderManagerState.setBackground(Color.GREEN);
                                break;

                            case Paused:
                                startPauseAction.putValue(Action.SHORT_DESCRIPTION, "Start/resume seeker");
                                startPauseAction.putValue(Action.LARGE_ICON_KEY, Icons.getIcon("play.png"));
                                stopAction.setEnabled(true);
                                httpProviderManagerState.setBackground(Color.YELLOW);

                                break;

                            case Stopped:
                                startPauseAction.putValue(Action.SHORT_DESCRIPTION, "Start/resume seeker");
                                startPauseAction.putValue(Action.LARGE_ICON_KEY, Icons.getIcon("play.png"));
                                stopAction.setEnabled(false);
                                httpProviderManagerState.setBackground(Color.RED);
                                break;
                        }
                    }
                });
            }
        });

    }

    private void setControlsToHttpProviderActionBegin() {
        startPauseAction.setEnabled(false);
        stopAction.setEnabled(false);
        httpProviderManagerState.setText("Proceding...");
        httpProviderManagerState.setBackground(Color.CYAN);
    }

    private void showInformationDetail(final Information information) {
        MainFrame.getInstance().invokeLater(new Runnable() {

            @Override
            public void run() {
                informationDetailPanel.getValue().setInformation(information);
                mainSplit.setRightComponent(informationDetailPanel.getValue());
            }
        });

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainSplit = new javax.swing.JSplitPane();
        browseScrollPane = new javax.swing.JScrollPane();
        browser = new javax.swing.JTree();
        jToolBar1 = new javax.swing.JToolBar();
        playButton = new javax.swing.JButton();
        stopButton = new javax.swing.JButton();
        httpProviderManagerState = new javax.swing.JLabel();

        mainSplit.setDividerLocation(100);

        browser.setModel(new net.stuffrepos.bricknetcenter.gui.informations.InformationsBrowserTreeModel());
        browseScrollPane.setViewportView(browser);

        mainSplit.setLeftComponent(browseScrollPane);

        jToolBar1.setFloatable(false);
        jToolBar1.setRollover(true);

        playButton.setAction(startPauseAction);
        playButton.setFocusable(false);
        playButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        playButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        playButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                playButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(playButton);

        stopButton.setAction(stopAction);
        stopButton.setFocusable(false);
        stopButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        stopButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(stopButton);

        httpProviderManagerState.setFont(new java.awt.Font("Dialog", 1, 18)); // NOI18N
        httpProviderManagerState.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        httpProviderManagerState.setText("httpProviderManagerStatus");
        httpProviderManagerState.setOpaque(true);
        jToolBar1.add(httpProviderManagerState);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(mainSplit, javax.swing.GroupLayout.DEFAULT_SIZE, 401, Short.MAX_VALUE)
            .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(mainSplit, javax.swing.GroupLayout.DEFAULT_SIZE, 589, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_playButtonActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JScrollPane browseScrollPane;
    private javax.swing.JTree browser;
    private javax.swing.JLabel httpProviderManagerState;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JSplitPane mainSplit;
    private javax.swing.JButton playButton;
    private javax.swing.JButton stopButton;
    // End of variables declaration//GEN-END:variables

    private void setSelectedNode(Object node) {

        try {
            this.selectedNode = node;

            if (this.selectedNode == null) {
                showMainDetail();
            } else if (node instanceof InformationsBrowserTreeModel.InformationTreeNode) {
                InformationsBrowserTreeModel.InformationTreeNode informationTreeNode = (InformationsBrowserTreeModel.InformationTreeNode) node;
                if (informationTreeNode.getInformation() != null) {
                    showInformationDetail(informationTreeNode.getInformation());
                } else {
                    showMainDetail();
                }
            }
        } catch (Exception ex) {
            MainFrame.getInstance().registerException("Fail on selecting information", ex);
        }
    }

    private void showMainDetail() {
        MainFrame.getInstance().invokeLater(new Runnable() {

            @Override
            public void run() {
                mainSplit.setRightComponent(mainDetailPanel.getValue());
            }
        });

    }
}
